<template>
<div v-if="!isPreview" :class="$style.root" @mouseleave="onMouseleave" :readonly="readonly">
    <span :class="$style.item" v-for="i in currentMax" :key="i" :status="getFullStatus(i)"
        @mousemove="onMousemove(i, $event)"
        @click="select(i)" :half="getHalfStatus(i)"
        ref="star">
        <span :class="$style.mask" :style="{width: decimalWidth + '%'}"></span>
        <u-popup :class="$style.popup" v-if="showTooltip && !$env.VUE_APP_DESIGNER" trigger="manual" :opened="hoverIndex === i" :placement="placement">
            {{ tooltips[tooltipIndex] }}
        </u-popup>
    </span>
    <span :class="$style.text" v-if="showText">{{ texts[tooltipIndex] }}</span>
    <span :class="$style.text" v-if="showValue"> {{ currentValue }} </span>
</div>
<u-preview v-else :text="showText ? texts[tooltipIndex] : String(currentValue) || '--'"></u-preview>
</template>

<script>
import { sync } from '@lcap/vue2-utils';
import MField from '../m-field.vue';
import UPreview from '../u-text.vue';
import MPreview from '../u-text.vue/preview';

export default {
    name: 'u-rate',
    mixins: [
      MField,
      MPreview,
      sync({
        value: 'currentValue',
        readonly: 'readonly',
        preview: 'isPreview',
      })
    ],
    components: {
      UPreview,
    },
    props: {
        value: { type: Number, default: 0 },
        max: { type: Number, default: 5 },
        readonly: { type: Boolean, default: false },
        texts: {
            type: Array,
            default() {
                return ['极差', '失望', '一般', '满意', '惊喜'];
            },
        },
        allowHalf: { type: Boolean, default: false },
        clearable: { type: Boolean, default: false },
        showText: { type: Boolean, default: false },
        showTooltip: { type: Boolean, default: false },
        showValue: { type: Boolean, default: false },
        preview: { type: Boolean, default: false },
        placement: { type: String, default: 'top' },
        tooltips: {
            type: Array,
            default() {
                return ['极差', '失望', '一般', '满意', '惊喜'];
            },
        },
    },
    computed: {
        decimalWidth() {
            if (this.allowHalf) {
                return 50;
            } else {
                return this.currentValue * 100 - Math.floor(this.currentValue) * 100;
            }
        },
        tooltipIndex(){
            if (this.isHover) {
                return this.hoverIndex - 1;
            } else {
                const value = Math.ceil(this.currentValue);
                return value - 1;
            }
        },
        currentMax() {
            return this.max > 10000 ? 10000 : this.max;
        },
    },
    data() {
        const list = [];
        for (let i = 0; i < 5; i++)
            list.push({ index: i });
        return {
            currentValue: Number(this.value) > this.max ? this.max : Number(this.value),
            list,
            isHover: false,
            hoverIndex: -1,
            pointerAtLeftHalf: false,
        };
    },
    watch: {
        value(value, oldValue) {
            this.currentValue = Number(value);
        },
        currentValue(value, oldValue) {
            this.$emit('change', {
                value,
                oldValue,
            }, this);
        },
    },
    methods: {
        onMousemove(i, $event) {
            if (this.readonly) {
                return false;
            }
            if (this.allowHalf) {
                const target = this.$refs.star[i-1];
                this.pointerAtLeftHalf = $event.offsetX * 2 <= target.clientWidth;
            }
            this.isHover = true;
            this.hoverIndex = i;
        },
        onMouseleave() {
            this.pointerAtLeftHalf = false;
            this.isHover = false;
            this.hoverIndex = -1;
        },
        select(i) {
            if (this.readonly) {
                return false;
            }
            const newValue = this.pointerAtLeftHalf? i - 0.5 :i;
            let isReset = false;
            if (this.clearable) {
                isReset = this.currentValue === newValue;
            }
            this.onMouseleave();
            this.currentValue = isReset? 0 : newValue;
            this.$emit('input', this.currentValue, this);
            this.$emit('update:value', this.currentValue, this);
        },
        showMask(index){
            const allowDecimal = this.readonly && this.currentValue > index -1 && index > this.currentValue;
            const allowClickHalf = this.allowHalf && this.pointerAtLeftHalf && this.hoverIndex === index;
            return allowDecimal || allowClickHalf;
        },
        getFullStatus(index) {
            let isFull = false;
            if(this.isHover) {
                if(this.pointerAtLeftHalf) {
                    isFull = index <= this.hoverIndex - 0.5;
                } else {
                    isFull = index <= this.hoverIndex;
                }
            } else {
                isFull = index<= this.currentValue;
            }
            return isFull? 'full' : '';
        },
        getHalfStatus(index) {
            if (this.isHover) {
                return this.hoverIndex === index && this.pointerAtLeftHalf;
            } else {
                return this.currentValue > index -1 && this.currentValue < index;
            }
        }
    },
};
</script>

<style module>
.root[readonly] .item {
    cursor: default;
}
.root[readonly] .item:hover{
    transform: scale(1);
}

.item {
    display: inline-block;
    font-size: var(--rate-size);
    transition: all .3s ease;
    color: var(--rate-color);
    cursor: var(--cursor-pointer);
    position: relative;
}

.item:hover {
    transform: scale(1.2);
}

.item::before {
content: "\e64a";
    font-family: "lcap-ui-icons";
    font-style: normal;
    font-weight: normal;
    font-variant: normal;
    text-decoration: inherit;
    text-rendering: optimizeLegibility;
    text-transform: none;
    -moz-osx-font-smoothing: grayscale;
    -webkit-font-smoothing: antialiased;
    font-smoothing: antialiased;
}

.item:not(:last-child) {
    margin-right: var(--rate-space);
}

.item[status="full"] {
    color: var(--rate-color-full);
}
.item[half] .mask {
    opacity: 1;
}

.mask {
    position: absolute;
    height: 100%;
    left: 0;
    overflow: hidden;
    color: var(--rate-color-full);
    opacity: 0;
    width: 50%;
    transition: all .3s;
}
.mask::before {
content: "\e64a";
    font-family: "lcap-ui-icons";
    font-style: normal;
    font-weight: normal;
    font-variant: normal;
    text-decoration: inherit;
    text-rendering: optimizeLegibility;
    text-transform: none;
    -moz-osx-font-smoothing: grayscale;
    -webkit-font-smoothing: antialiased;
    font-smoothing: antialiased;
}

.text {
    color: var(--rate-text-color);
    vertical-align: 2px;
}

.popup {
    background: var(--rate-popup-background);
    min-width: initial;
}
</style>
